module ysyx_23060189_AXI_Lite_master #
(
  parameter addrwidth = 32,
  parameter datawidth = 32
)
(
  /* Master <=> Master interface */
  input  wire                   ren,
  input  wire [addrwidth-1:0]   raddr,
  output reg  [datawidth-1:0]   rdata,
  output reg                    rvalid,

  input  wire                   wen,
  input  wire [addrwidth-1:0]   waddr,
  input  wire [datawidth-1:0]   wdata,
  input  wire [7:0]             wmask,
  output reg                    wdone,

  /* Master interface <=> Arbiter */
  // Global
  input  wire                   ACLK,
  input  wire                   ARESETn,

  // Write address channel
  output reg                    AWVALID,
  input  wire                   AWREADY,
  output reg  [addrwidth-1:0]   AWADDR,
  output wire [2:0]             AWPROT,

  // Write data channel
  output reg                    WVALID,
  input  wire                   WREADY,
  output reg  [datawidth-1:0]   WDATA,
  output wire [datawidth/8-1:0] WSTRB,

  // Write response channel
  input  wire                   BVALID,
  output reg                    BREADY,
  input  wire [1:0]             BRESP,

  // Read address channel
  output reg                    ARVALID,
  input  wire                   ARREADY,
  output reg  [addrwidth-1:0]   ARADDR,
  output wire [2:0]             ARPROT,

  // Read data channel
  input  wire                   RVALID,
  output reg                    RREADY,
  input  wire [datawidth-1:0]   RDATA,
  input  wire [1:0]             RRESP
);

  // raising edge of wen
  wire wen_raise;
  reg  wen_cur;
  reg  wen_pre;

  // raising edge of ren
  wire ren_raise;
  reg  ren_cur;
  reg  ren_pre;

  assign AWPROT = 3'h0;
  assign WSTRB  = wmask[datawidth/8-1 : 0];
  assign ARPROT = 3'h0;

  // output rvalid
  always @(posedge ACLK) begin
    if (ARESETn == 0) rvalid <= 0;
    else if (RVALID && RREADY) rvalid <= 1;
    else rvalid <= 0;
  end
  // output rdata
  always @(posedge ACLK) begin
    if (ARESETn == 0) rdata <= 32'b0;
    else if(RVALID && RREADY) rdata <= RDATA;
    else rdata <= rdata;
  end

  // output wdone
  always @(posedge ACLK) begin
    if (ARESETn == 0) wdone <= 0;
    else if (BVALID && BREADY) wdone <= 1'b1;
    else wdone <= 0;
  end

  // get raising edge of wen
  assign wen_raise = (!wen_pre) && wen_cur;
  always @(posedge ACLK) begin
    if (ARESETn == 0) begin
      wen_cur <= 0;
      wen_pre <= 0;
    end
    else begin
      wen_cur <= wen;
      wen_pre <= wen_cur;
    end
  end

  // get raising edge of wen
  assign ren_raise = (!ren_pre) && ren_cur;
  always @(posedge ACLK) begin
    if (ARESETn == 0) begin
      ren_cur <= 0;
      ren_pre <= 0;
    end
    else begin
      ren_cur <= ren;
      ren_pre <= ren_cur;
    end
  end

  //---------------------
  //Write address channel
  //---------------------
  // AWVALID
  always @(posedge ACLK) begin
    if (ARESETn == 0) AWVALID <= 0;
    else begin
      if (AWVALID && AWREADY) AWVALID <= 0;
      else if (~AWVALID && wen_raise) AWVALID <= 1;
      else AWVALID <= AWVALID;
    end
  end

  // AWADDR
  always @(posedge ACLK) begin
    if (ARESETn == 0) AWADDR <= 0;
    else begin
      if (wen_raise) AWADDR <= waddr;
      else AWADDR <= AWADDR;
    end
  end

  //---------------------
  //Write data channel
  //---------------------
  // WVALID
  always @(posedge ACLK) begin
    if (ARESETn == 0) WVALID <= 0;
    else begin
      if (WVALID && WREADY) WVALID <= 0;
      else if (~WVALID && wen_raise) WVALID <= 1;
      else WVALID <= WVALID;
    end
  end

  // WDATA
  always @(posedge ACLK) begin
    if (ARESETn == 0) WDATA <= 0;
    else begin
      if (wen_raise) WDATA <= wdata;
      else WDATA <= WDATA;
    end
  end

  //---------------------
  //Write response channel
  //---------------------
  // BREADY
  always @(posedge ACLK) begin
    if (ARESETn == 0) BREADY <= 0;
    else if (BVALID && ~BREADY) BREADY <= 1;
    else if (BREADY) BREADY <= 0;
    else BREADY <= BREADY;
  end

  //---------------------
  //Read address channel
  //---------------------
  // ARVALID
  always @(posedge ACLK) begin
    if (ARESETn == 0) ARVALID <= 0;
    else begin
      if (ARVALID && ARREADY) ARVALID <= 0;
      else if (~ARVALID && ren_raise) ARVALID <= 1;
      else ARVALID <= ARVALID;
    end
  end

  // ARADDR
  always @(posedge ACLK) begin
    if (ARESETn == 0) ARADDR <= 0;
    else begin
      if (ren_raise) ARADDR <= raddr;
      else ARADDR <= ARADDR;
    end
  end

  //---------------------
  //Read data channel
  //---------------------
  // RREADY
  always @(posedge ACLK) begin
    if (ARESETn == 0) RREADY <= 0;
    else begin
      if (RVALID && ~RREADY) RREADY <= 1;
      else if (RREADY) RREADY <= 0;
      else RREADY <= RREADY;
    end
  end

endmodule
